home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / What's New? / Development Kits / Mac OS / USB DDK 1.4.6f4 / Examples / KeyboardModule / KeyIn.c < prev   
Encoding:
C/C++ Source or Header  |  2000-09-25  |  16.9 KB  |  660 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        KeyIn.c
  3.  
  4.     Contains:    ADB keyboard simulation (non-shim based).
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1998-2000 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12. /*
  13.  USB Keyboard Translation to Macintosh 
  14.  */
  15.  
  16. #include <Types.h>
  17. #include <Events.h>
  18. #include <Resources.h>
  19. #include <LowMem.h>
  20. #include <USB.h>
  21. #include "KeyboardModule.h"
  22.  
  23.  
  24. #define DOWN        0
  25. #define UP            1
  26.  
  27. #define TRUE        1
  28. #define FALSE        0
  29.  
  30. // Definitions of modifier keys that are duplicated on keyboards
  31. // w/ their USB Raw scan codes
  32. //
  33. #define USBLEFTSHIFTKEY        0xE1
  34. #define USBRIGHTSHIFTKEY    0xE5
  35. #define USBLEFTCONTROLKEY    0xE0
  36. #define USBRIGHTCONTROLKEY    0xE4
  37. #define USBLEFTOPTIONKEY    0xE2
  38. #define USBRIGHTOPTIONKEY    0xE6
  39. #define USBLEFTAPPLEKEY        0xE3
  40. #define USBRIGHTAPPLEKEY    0xE7
  41.  
  42. #define FakeADBAddr        16
  43. #define FakeKBDType        2        // this should be the same as the Apple extended keyboard for now
  44.  
  45. static UInt32    myKeyMAP[4];
  46. static UInt32    keyTransState;
  47. static Handle    handleKCHR;
  48. static UInt8*    KCHRptr;
  49.  
  50. static UInt16    gLeftShiftKey = 0x0;
  51. static UInt16    gRightShiftKey = 0x0;
  52. static UInt16    gLeftControlKey = 0x0;
  53. static UInt16    gRightControlKey = 0x0;
  54. static UInt16    gLeftOptionKey = 0x0;
  55. static UInt16    gRightOptionKey = 0x0;
  56. static UInt16    gLeftAppleKey = 0x0;
  57. static UInt16    gRightAppleKey = 0x0;
  58.  
  59.  
  60. typedef KeyMap * KeyMapPtr;
  61.  
  62. /* prototypes */
  63. Boolean KeyInArray(UInt8 key, UInt8 *array, UInt16 len);
  64. Boolean SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value); 
  65. void  PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state);
  66. static Boolean IsModifierKeyAlreadyDown( UInt16 rawUSBkeyCode );
  67. static void UpdateModifiersStatus( UInt16 rawUSBkeyCode, UInt8 keyDirection );
  68.  
  69. /* when we move to master interfaces we can get this stuff from LowMem.h */
  70. /* be sure to turn on DIRECT_LOWMEM_ACCESSORS */
  71. #define LMSetKbdVars(value) ((*(short *)0x0216) = (value))
  72. #define LMSetKeyLast(value) ((*(short *)0x0184) = (value))
  73. #define LMSetKeyTime(value) ((*(long *)0x0186) = (value))
  74. #define LMSetKeyRepTime(value) ((*(long *)0x018A) = (value))
  75. #define LMSetKeyMap(KeyMapValue)    BlockMoveData((Ptr)(KeyMapValue), (Ptr)0x0174, sizeof(KeyMap))
  76.  
  77.  
  78. // index represents USB keyboard usage value, content is Mac virtual keycode
  79. static UInt8    USBKMAP[256] = {  
  80.     0xFF,     /* 00 no event */        
  81.     0xFF,    /* 01 ErrorRollOver */    
  82.     0xFF,    /* 02 POSTFail */    
  83.     0xFF,    /* 03 ErrorUndefined */    
  84.     0x00,    /* 04 A */
  85.     0x0B,    /* 05 B */
  86.     0x08,    /* 06 C */
  87.     0x02,    /* 07 D */
  88.     0x0E,    /* 08 E */
  89.     0x03,    /* 09 F */
  90.     0x05,    /* 0A G */
  91.     0x04,    /* 0B H */
  92.     0x22,    /* 0C I */
  93.     0x26,    /* 0D J */
  94.     0x28,    /* 0E K */
  95.     0x25,    /* 0F L */
  96.  
  97.     0x2E,     /* 10 M */        
  98.     0x2D,    /* 11 N */    
  99.     0x1F,    /* 12 O */    
  100.     0x23,    /* 13 P */    
  101.     0x0C,    /* 14 Q */
  102.     0x0F,    /* 15 R */
  103.     0x01,    /* 16 S */
  104.     0x11,    /* 17 T */
  105.     0x20,    /* 18 U */
  106.     0x09,    /* 19 V */
  107.     0x0D,    /* 1A W */
  108.     0x07,    /* 1B X */
  109.     0x10,    /* 1C Y */
  110.     0x06,    /* 1D Z */
  111.     0x12,    /* 1E 1/! */
  112.     0x13,    /* 1F 2/@ */
  113.  
  114.     0x14,     /* 20 3 # */        
  115.     0x15,    /* 21 4 $ */    
  116.     0x17,    /* 22 5 % */    
  117.     0x16,    /* 23 6 ^ */    
  118.     0x1A,    /* 24 7 & */
  119.     0x1C,    /* 25 8 * */
  120.     0x19,    /* 26 9 ( */
  121.     0x1D,    /* 27 0 ) */
  122.     0x24,    /* 28 Return (Enter) */
  123.     0x35,    /* 29 ESC */
  124.     0x33,    /* 2A Delete (Backspace) */
  125.     0x30,    /* 2B Tab */
  126.     0x31,    /* 2C Spacebar */
  127.     0x1B,    /* 2D - _ */
  128.     0x18,    /* 2E = + */
  129.     0x21,    /* 2F [ { */
  130.  
  131.     0x1E,     /* 30 ] } */        
  132.     0x2A,    /* 31 \ | */    
  133.     0xFF,    /* 32 Non-US # and ~ (what?!!!) */    
  134.     0x29,    /* 33 ; : */    
  135.     0x27,    /* 34 ' " */
  136.     0x32,    /* 35 ` ~ */
  137.     0x2B,    /* 36 , < */
  138.     0x2F,    /* 37 . > */
  139.     0x2C,    /* 38 / ? */
  140.     0x39,    /* 39 Caps Lock */
  141.     0x7A,    /* 3A F1 */
  142.     0x78,    /* 3B F2 */
  143.     0x63,    /* 3C F3 */
  144.     0x76,    /* 3D F4 */
  145.     0x60,    /* 3E F5 */
  146.     0x61,    /* 3F F6 */
  147.  
  148.     0x62,     /* 40 F7 */        
  149.     0x64,    /* 41 F8 */    
  150.     0x65,    /* 42 F9 */    
  151.     0x6D,    /* 43 F10 */    
  152.     0x67,    /* 44 F11 */
  153.     0x6F,    /* 45 F12 */
  154.     0x69,    /* 46 F13/PrintScreen */
  155.     0x6B,    /* 47 F14/ScrollLock */
  156.     0x71,    /* 48 F15/Pause */                
  157.     0x72,    /* 49 Insert */
  158.     0x73,    /* 4A Home */
  159.     0x74,    /* 4B PageUp */
  160.     0x75,    /* 4C Delete Forward */
  161.     0x77,    /* 4D End */
  162.     0x79,    /* 4E PageDown */
  163.     0x7C,    /* 4F RightArrow */
  164.  
  165.     0x7B,     /* 50 LeftArrow */        
  166.     0x7D,    /* 51 DownArrow */    
  167.     0x7E,    /* 52 UpArrow */    
  168.     0x47,    /* 53 NumLock/Clear */    
  169.     0x4B,    /* 54 Keypad / */
  170.     0x43,    /* 55 Keypad * */
  171.     0x4E,    /* 56 Keypad - */
  172.     0x45,    /* 57 Keypad + */
  173.     0x4C,    /* 58 Keypad Enter */
  174.     0x53,    /* 59 Keypad 1 */
  175.     0x54,    /* 5A Keypad 2 */
  176.     0x55,    /* 5B Keypad 3 */
  177.     0x56,    /* 5C Keypad 4 */
  178.     0x57,    /* 5D Keypad 5 */
  179.     0x58,    /* 5E Keypad 6 */
  180.     0x59,    /* 5F Keypad 7 */
  181.  
  182.     0x5B,     /* 60 Keypad 8 */        
  183.     0x5C,    /* 61 Keypad 9 */    
  184.     0x52,    /* 62 Keypad 0 */    
  185.     0x41,    /* 63 Keypad . */    
  186.     0xFF,    /* 64 Non-US \ and  | (what ??!!) */
  187.     0x6E,    /* 65 ApplicationKey (not on a mac!)*/
  188.     0x7F,    /* 66 PowerKey  */
  189.     0x51,    /* 67 Keypad = */
  190.     0x69,    /* 68 F13 */
  191.     0x6B,    /* 69 F14 */
  192.     0x71,    /* 6A F15 */
  193.     0xFF,    /* 6B F16 */
  194.     0xFF,    /* 6C F17 */
  195.     0xFF,    /* 6D F18 */
  196.     0xFF,    /* 6E F19 */
  197.     0xFF,    /* 6F F20 */
  198.  
  199.     0x5B,     /* 70 F21 */        
  200.     0x5C,    /* 71 F22 */    
  201.     0x52,    /* 72 F23 */    
  202.     0x41,    /* 73 F24 */    
  203.     0xFF,    /* 74 Execute */
  204.     0xFF,    /* 75 Help */
  205.     0x7F,    /* 76 Menu */
  206.     0x4C,    /* 77 Select */
  207.     0x69,    /* 78 Stop */
  208.     0x6B,    /* 79 Again */
  209.     0x71,    /* 7A Undo */
  210.     0xFF,    /* 7B Cut */
  211.     0xFF,    /* 7C Copy */
  212.     0xFF,    /* 7D Paste */
  213.     0xFF,    /* 7E Find */
  214.     0xFF,    /* 7F Mute */
  215.     
  216.     0xFF,     /* 80 no event */        
  217.     0xFF,    /* 81 no event */    
  218.     0xFF,    /* 82 no event */    
  219.     0xFF,    /* 83 no event */    
  220.     0xFF,    /* 84 no event */
  221.     0xFF,    /* 85 no event */
  222.     0xFF,    /* 86 no event */
  223.     0xFF,    /* 87 no event */
  224.     0xFF,    /* 88 no event */
  225.     0xFF,    /* 89 no event */
  226.     0xFF,    /* 8A no event */
  227.     0xFF,    /* 8B no event */
  228.     0xFF,    /* 8C no event */
  229.     0xFF,    /* 8D no event */
  230.     0xFF,    /* 8E no event */
  231.     0xFF,    /* 8F no event */
  232.  
  233.     0xFF,     /* 90 no event */        
  234.     0xFF,    /* 91 no event */    
  235.     0xFF,    /* 92 no event */    
  236.     0xFF,    /* 93 no event */    
  237.     0xFF,    /* 94 no event */
  238.     0xFF,    /* 95 no event */
  239.     0xFF,    /* 96 no event */
  240.     0xFF,    /* 97 no event */
  241.     0xFF,    /* 98 no event */
  242.     0xFF,    /* 99 no event */
  243.     0xFF,    /* 9A no event */
  244.     0xFF,    /* 9B no event */
  245.     0xFF,    /* 9C no event */
  246.     0xFF,    /* 9D no event */
  247.     0xFF,    /* 9E no event */
  248.     0xFF,    /* 9F no event */
  249.  
  250.     0xFF,     /* A0 no event */        
  251.     0xFF,    /* A1 no event */    
  252.     0xFF,    /* A2 no event */    
  253.     0xFF,    /* A3 no event */    
  254.     0xFF,    /* A4 no event */
  255.     0xFF,    /* A5 no event */
  256.     0xFF,    /* A6 no event */
  257.     0xFF,    /* A7 no event */
  258.     0xFF,    /* A8 no event */
  259.     0xFF,    /* A9 no event */
  260.     0xFF,    /* AA no event */
  261.     0xFF,    /* AB no event */
  262.     0xFF,    /* AC no event */
  263.     0xFF,    /* AD no event */
  264.     0xFF,    /* AE no event */
  265.     0xFF,    /* AF no event */
  266.  
  267.     0xFF,     /* B0 no event */        
  268.     0xFF,    /* B1 no event */    
  269.     0xFF,    /* B2 no event */    
  270.     0xFF,    /* B3 no event */    
  271.     0xFF,    /* B4 no event */
  272.     0xFF,    /* B5 no event */
  273.     0xFF,    /* B6 no event */
  274.     0xFF,    /* B7 no event */
  275.     0xFF,    /* B8 no event */
  276.     0xFF,    /* B9 no event */
  277.     0xFF,    /* BA no event */
  278.     0xFF,    /* BB no event */
  279.     0xFF,    /* BC no event */
  280.     0xFF,    /* BD no event */
  281.     0xFF,    /* BE no event */
  282.     0xFF,    /* BF no event */
  283.  
  284.     0xFF,     /* C0 no event */        
  285.     0xFF,    /* C1 no event */    
  286.     0xFF,    /* C2 no event */    
  287.     0xFF,    /* C3 no event */    
  288.     0xFF,    /* C4 no event */
  289.     0xFF,    /* C5 no event */
  290.     0xFF,    /* C6 no event */
  291.     0xFF,    /* C7 no event */
  292.     0xFF,    /* C8 no event */
  293.     0xFF,    /* C9 no event */
  294.     0xFF,    /* CA no event */
  295.     0xFF,    /* CB no event */
  296.     0xFF,    /* CC no event */
  297.     0xFF,    /* CD no event */
  298.     0xFF,    /* CE no event */
  299.     0xFF,    /* CF no event */
  300.  
  301.     0xFF,     /* D0 no event */        
  302.     0xFF,    /* D1 no event */    
  303.     0xFF,    /* D2 no event */    
  304.     0xFF,    /* D3 no event */    
  305.     0xFF,    /* D4 no event */
  306.     0xFF,    /* D5 no event */
  307.     0xFF,    /* D6 no event */
  308.     0xFF,    /* D7 no event */
  309.     0xFF,    /* D8 no event */
  310.     0xFF,    /* D9 no event */
  311.     0xFF,    /* DA no event */
  312.     0xFF,    /* DB no event */
  313.     0xFF,    /* DC no event */
  314.     0xFF,    /* DD no event */
  315.     0xFF,    /* DE no event */
  316.     0xFF,    /* DF no event */
  317.  
  318.     0x3B,     /* E0 left control key */        
  319.     0x38,    /* E1 left shift key key */    
  320.     0x3A,    /* E2 left alt/option key */    
  321.     0x37,    /* E3 left GUI (windows/cmd) key */    
  322.     
  323.     0x3B,    /* E4 right control key */ 
  324.     0x38,    /* E5 right shift key key */ 
  325.     0x3A,    /* E6 right alt/option key */ 
  326.     0x37,    /* E7 right GUI (windows/cmd) key */
  327.     0xFF,    /* E8 no event */
  328.     0xFF,    /* E9 no event */
  329.     0xFF,    /* EA no event */
  330.     0xFF,    /* EB no event */
  331.     0xFF,    /* EC no event */
  332.     0xFF,    /* ED no event */
  333.     0xFF,    /* EE no event */
  334.     0xFF,    /* EF no event */
  335.     
  336.     0xFF,     /* F0 no event */        
  337.     0xFF,    /* F1 no event */    
  338.     0xFF,    /* F2 no event */    
  339.     0xFF,    /* F3 no event */    
  340.     0xFF,    /* F4 no event */
  341.     0xFF,    /* F5 no event */
  342.     0xFF,    /* F6 no event */
  343.     0xFF,    /* F7 no event */
  344.     0xFF,    /* F8 no event */
  345.     0xFF,    /* F9 no event */
  346.     0xFF,    /* FA no event */
  347.     0xFF,    /* FB no event */
  348.     0xFF,    /* FC no event */
  349.     0xFF,    /* FD no event */
  350.     0xFF,    /* FE no event */
  351.     0xFF,    /* FF no event */
  352. };
  353.         
  354. void
  355. InitUSBKeyboard()
  356. {
  357.     if (KCHRptr == 0)
  358.     {
  359.         handleKCHR = GetResource('KCHR',0);    // US keyboard mapping (handled differently by ADB Mgr)
  360.         HLock(handleKCHR);
  361.         KCHRptr = (UInt8 *)*handleKCHR;
  362.     }
  363. }
  364.  
  365.  
  366.  
  367. void PostUSBKeyToMac(UInt16 rawUSBkey)
  368. {
  369.     static    UInt8    oldLEDState = 0x00;
  370.     static    UInt8    newLEDState = 0x00;
  371.     
  372.     static    UInt8    capsLockState = 0x00;
  373.     static    UInt8    numLockState = 0x00;
  374.     static    UInt8    scrollLockState = 0x00;
  375.     
  376.     register UInt8    virtualKeycode, keystate;
  377.  
  378.     // Get the state (up/down) of the key pressed and then clear it so that
  379.     // we get the raw key code
  380.     //
  381.     keystate = (rawUSBkey & 0x8000) ? UP : DOWN;
  382.     rawUSBkey &= 0x0FF;
  383.     
  384.     // Do different stuff is the key is down or up
  385.     //
  386.     if (keystate == DOWN)
  387.     {
  388.         newLEDState = oldLEDState;
  389.         
  390.         switch (rawUSBkey)
  391.         {
  392.             // Note:  This switch statement is being left it to make it easy to add "toggling" keys in the future.
  393.             //        it used to support toggled numlock & scroll lock...  It doesn't anymore.
  394.             //
  395.             case kUSBCapsLockKey:
  396.                 newLEDState ^= (1 << kCapsLockLED);
  397.                 keystate = (newLEDState & (1 << kCapsLockLED)) ? DOWN : UP;
  398.                 break;
  399.         }
  400.         
  401.         // Set the LED if appropriate
  402.         //
  403.         if (newLEDState != oldLEDState)
  404.         {
  405.             oldLEDState = newLEDState;
  406.             USBHIDControlDevice(kHIDSetLEDStateByBits, &newLEDState);
  407.         }
  408.     }
  409.     else
  410.     {
  411.         // We received a key up event
  412.         //
  413.         switch (rawUSBkey)
  414.         {
  415.             // Note:  This switch statement is being left it to make it easy to add "toggling" keys in the future.
  416.             //
  417.             case kUSBCapsLockKey:
  418.                 return;
  419.                 break;
  420.         }
  421.         
  422.         // Check to see if we have the duplicate key already down.  If so, then we don't post the key up event
  423.         //
  424.         if ( IsModifierKeyAlreadyDown( rawUSBkey ) )
  425.             return;
  426.     }
  427.     
  428.     // Look up rawUSBkey in KMAP resource to get virtual keycode
  429.     //
  430.     if (rawUSBkey < sizeof(USBKMAP))
  431.     {
  432.         virtualKeycode = USBKMAP[rawUSBkey];
  433.     } 
  434.     else 
  435.     {
  436.         virtualKeycode = 0xFF;
  437.     }
  438.  
  439.     // Go ahead and tell MacOS to post the key event
  440.     //
  441.     PostADBKeyToMac(virtualKeycode, keystate);
  442.     
  443.     if (virtualKeycode == 0x7F)
  444.         PostADBKeyToMac(virtualKeycode, keystate);
  445.         
  446.     // Update our globals that keep track of modifier keys state
  447.     //
  448.     UpdateModifiersStatus( rawUSBkey, keystate );
  449. }
  450.  
  451. void 
  452. PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state)
  453. {
  454.     UInt32    keyEventMsg;
  455.     
  456.     if (virtualKeycode > 127) return;  // not handled by MacOS!
  457.     
  458.     // stop repeating
  459.     LMSetKeyLast(0);
  460.     LMSetKbdVars(0);
  461.     
  462.     // update our keymap
  463.     SetBit((UInt8 *)myKeyMAP, virtualKeycode, state == DOWN ? 1 : 0);
  464.     LMSetKeyMap(&myKeyMAP);
  465.  
  466.     // set this keyboard as the last keyboard
  467.     LMSetKbdLast(FakeADBAddr);
  468.     LMSetKbdType(FakeKBDType);
  469.     
  470.     // call KeyTrans to get character code
  471.     virtualKeycode |= ((myKeyMAP[1]<<9) & 0x00FE00) | ((myKeyMAP[1]>>7) & 0x0100) | ((state==UP) ? 0x080 : 0);
  472.     keyEventMsg = KeyTranslate(KCHRptr, virtualKeycode , &keyTransState);
  473.     virtualKeycode &= 0x7F;
  474.     
  475.     if (keyEventMsg & 0xFFFF0000) {
  476.         // post event
  477.         UInt32 event =(keyEventMsg & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00)  | ((keyEventMsg>>16) & 0x0FF);
  478.         if (state == DOWN){
  479.             UInt32 ticks = TickCount();
  480.             LMSetKeyTime(ticks);
  481.             LMSetKeyRepTime(ticks);
  482.             LMSetKeyLast(event & 0x0FFFF);
  483.             LMSetKbdVars((event>>16) & 0x0FFFF);
  484.         }        
  485.         PostEvent((state == DOWN ? keyDown : keyUp), event);
  486.     }
  487.     if (keyEventMsg & 0x0000FFFF) {
  488.         // post event
  489.         UInt32 event =((keyEventMsg<<16) & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00)  | (keyEventMsg & 0x0FF);
  490.         if (state == DOWN){
  491.             UInt32 ticks = TickCount();
  492.             LMSetKeyTime(ticks);
  493.             LMSetKeyRepTime(ticks);
  494.             LMSetKeyLast(event & 0x0FFFF);
  495.             LMSetKbdVars((event>>16) & 0x0FFFF);
  496.         }        
  497.         PostEvent((state == DOWN ? keyDown : keyUp), event);
  498.     }
  499. }
  500.  
  501. //========================================================================================
  502. //
  503. // Sets the bitmapArray[index] to value.  Returns old value;
  504. //
  505. //========================================================================================
  506. //
  507. Boolean SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value)
  508. {    
  509.     UInt32    mask = 0x1 << (index % 8 );
  510.     Boolean    oldVal;
  511.     
  512.     oldVal = (bitmapArray[index/8] & mask) ? TRUE : FALSE;
  513.     
  514.     if (value){
  515.         bitmapArray[index/8] |= mask;
  516.     }else{
  517.         bitmapArray[index/8] &= ~mask;
  518.     }
  519.     
  520.     return (oldVal);
  521. }
  522.  
  523. //========================================================================================
  524. //
  525. //  IsModifierKeyAlreadyDown
  526. //
  527. //  This routine will check to see if the key that was hit is a modifier with left and right
  528. //  keys in they keyboard.  If so, it will see if the "other" key is down and return if true.
  529. //  
  530. //========================================================================================
  531. //
  532. static Boolean IsModifierKeyAlreadyDown( UInt16 rawUSBkeyCode )
  533. {
  534.     Boolean returnValue = false;
  535.     UInt32    keySum = 0;
  536.     
  537.     // Optimize by adding all the pressed key globals:
  538.     //
  539.     keySum = ( gLeftShiftKey + gLeftControlKey + gLeftOptionKey + gLeftAppleKey + 
  540.                gRightShiftKey + gRightControlKey + gRightOptionKey + gRightAppleKey );
  541.     
  542.     if ( keySum > 0 )
  543.     {
  544.         // If the left modifier key is already pressed and this is a right modifier key UP,
  545.         // don't post the right modifier key UP
  546.         //
  547.         if ( gLeftShiftKey != 0x0 )
  548.             if ( rawUSBkeyCode == USBRIGHTSHIFTKEY )
  549.             {
  550.                 gRightShiftKey = 0;
  551.                 returnValue = true;;
  552.                 USBExpertStatusLevel(1, 0, "\pKBDHIDModule: Right Shift Key hit while Left Apple Shift pressed", (UInt32) gLeftShiftKey);
  553.             }
  554.     
  555.         if ( gLeftControlKey != 0x0 )
  556.             if ( rawUSBkeyCode == USBRIGHTCONTROLKEY )
  557.             {
  558.                 gRightControlKey = 0;
  559.                 returnValue = true;
  560.             }
  561.     
  562.         if ( gLeftOptionKey != 0x0 )
  563.             if ( rawUSBkeyCode == USBRIGHTOPTIONKEY )
  564.             {
  565.                 gRightOptionKey = 0;
  566.                 returnValue = true;
  567.             }
  568.     
  569.         if ( gLeftAppleKey != 0x0 )
  570.             if ( rawUSBkeyCode == USBRIGHTAPPLEKEY )
  571.             {
  572.                 gRightAppleKey = 0;
  573.                 returnValue = true;
  574.                 // USBExpertStatusLevel(1, 0, "\KBDHIDModule: Right Apple Key hit while Left Apple Key pressed", (UInt32) gLeftAppleKey);
  575.             }
  576.         
  577.         // If the right modifier key is already pressed and this is a left modifier key UP,
  578.         // don't post the left shift key UP
  579.         //
  580.         if ( gRightShiftKey != 0x0 )
  581.             if ( rawUSBkeyCode == USBLEFTSHIFTKEY )
  582.             {
  583.                 gLeftShiftKey = 0;
  584.                 returnValue = true;
  585.                 USBExpertStatusLevel(1, 0, "\pKBDHIDModule: Left Shift Key hit while Right Apple Shift pressed", (UInt32) gRightShiftKey);
  586.             }
  587.         
  588.         if ( gRightControlKey != 0x0 )
  589.             if ( rawUSBkeyCode == USBLEFTCONTROLKEY )
  590.             {
  591.                 gLeftControlKey = 0;
  592.                 returnValue = true;
  593.             }
  594.         
  595.         if ( gRightOptionKey != 0x0 )
  596.             if ( rawUSBkeyCode == USBLEFTOPTIONKEY )
  597.             {
  598.                 gLeftOptionKey = 0;
  599.                 returnValue = true;
  600.             }
  601.         
  602.         if ( gRightAppleKey != 0x0 )
  603.             if ( rawUSBkeyCode == USBLEFTAPPLEKEY )
  604.             {
  605.                 gLeftAppleKey = 0;
  606.                 returnValue = true;
  607.                 // USBExpertStatusLevel(1, 0, "\KBDHIDModule: Left Apple Key hit while Right Apple Key pressed", (UInt32) gRightAppleKey);
  608.             }
  609.     }
  610.     
  611.     return returnValue;
  612. }
  613.  
  614. //========================================================================================
  615. //
  616. //  UpdateModifiersStatus
  617. //
  618. //  This routine will set up a global for each modifier key that is duplicated on the
  619. //  the keyboard (left and right keys).  If the key is down, it will set the global to the
  620. //  raw USB keycode.  If the key is up, it will set it to 0.  This allows us to check later
  621. //  on whether the corresponding key of a modifier is already down and if so, then we don't
  622. //  process the key down event.
  623. //  
  624. //========================================================================================
  625. //
  626. static void UpdateModifiersStatus( UInt16 rawUSBkeyCode, UInt8 keyDirection )
  627. {
  628.     // Update our modifier globals if one of them was released
  629.     //
  630.     switch ( rawUSBkeyCode )
  631.     {
  632.         case USBLEFTSHIFTKEY:        gLeftShiftKey         = ( keyDirection == UP ? 0x0 : rawUSBkeyCode ); break;
  633.         case USBRIGHTSHIFTKEY:        gRightShiftKey         = ( keyDirection == UP ? 0x0 : rawUSBkeyCode ); break;
  634.         case USBLEFTCONTROLKEY:        gLeftControlKey     = ( keyDirection == UP ? 0x0 : rawUSBkeyCode ); break;
  635.         case USBRIGHTCONTROLKEY:    gRightControlKey     = ( keyDirection == UP ? 0x0 : rawUSBkeyCode ); break;
  636.         case USBLEFTOPTIONKEY:        gLeftOptionKey         = ( keyDirection == UP ? 0x0 : rawUSBkeyCode ); break;
  637.         case USBRIGHTOPTIONKEY:        gRightOptionKey     = ( keyDirection == UP ? 0x0 : rawUSBkeyCode ); break;
  638.         case USBLEFTAPPLEKEY:        gLeftAppleKey         = ( keyDirection == UP ? 0x0 : rawUSBkeyCode ); break;
  639.         case USBRIGHTAPPLEKEY:        gRightAppleKey         = ( keyDirection == UP ? 0x0 : rawUSBkeyCode ); break;
  640.     }
  641. }
  642.  
  643.  
  644. void USBDemoKeyIn(UInt32 refcon, void * theData)
  645. {
  646. #pragma unused (refcon)
  647.  
  648. USBHIDDataPtr    pTheKeyboardData;
  649. register        UInt8    i;
  650.  
  651.     pTheKeyboardData = (USBHIDDataPtr)theData;
  652.     for (i=0; i<pTheKeyboardData->kbd.keycount; i++)
  653.     {
  654.         // no shim installed, let's just post some Macintosh keyevents
  655.         PostUSBKeyToMac(pTheKeyboardData->kbd.usbkeycode[i]);
  656.     }
  657.  
  658. }
  659.  
  660.